/**
 * 解析所有模块下路由装配到主路由中
 * @type {Null}
 */
import {
  cacheKeys,
  store,
  log
} from '@/common/app/index.js'

const systemNames = window.systemConfig.SYSTEM_NAMES || [];

const utils = {
  // 根据路径获取路径的驼峰命名方式的名称，如/common/home/home将获取CommonHomeHome的名称信息
  getCamelName (path = '', exceptFirst = false) {
    let pathNames = (path.split('/')).map((item = '', index) => {
      let result = item;
      if (!exceptFirst || index !== 0) {
        result = item.charAt(0).toUpperCase() + item.slice(1);
      }
      return result;
    });
    return pathNames.join('');
  },

  // 对象深度合并，深度递归至最深处，非简单属性覆盖合并
  deepObjectMerge (a, b) {
    for (let key in b) {
      a[key] = a[key] && typeof a[key] === 'object' ? utils.deepObjectMerge(a[key], b[key]) : a[key] = b[key];
    }
    return a;
  },

  // 判断当前子系统是否需要进行封装
  hasSystem (systemName) {
    // 如果当前路由不是在common目录下，则根据配置的系统名称过滤
    if (systemName !== 'common') {
      // 如果有配置子系统加载，并且当前子系统不在配置的子系统配种，则认为不需要封装当前子系统
      if (systemNames && systemNames.length && systemNames.indexOf(systemName) === -1 && window.systemConfig.ONLY_LOAD_SYSTEM) {
        return false;
      }
    }
    return true;
  }
}

// 当前系统加载的所有路由列表，所有路由列表将缓存至缓存列表中（vuex中）
const routetList = [];

/* ******************************** 子系统配置信息加载 BEGIN ******************************** */
// 获取当前系统下的全局路由配置，该配置在系统名称目录下的router.js配置文件中
const systemRouterConfig = {};
// 将所有有页面的系统名称保存起来，用于菜单配置时选择子系统使用
const systemList = {};
const systemContext = require.context('@/modules', true, /\/systemConfig.js$/);
systemContext.keys().forEach(key => {
  const systemName = key.split('/')[1];
  // 如果当前子系统不需要封装，则不进行封装
  if (!utils.hasSystem(systemName)) {
    return;
  }
  const systemConfig = systemContext(key).default || {};
  // 将系统配置信息存放至系统配置中
  systemList[systemName] = systemConfig.system;
  // 将系统路由的配置存放至系统路由对象中
  systemRouterConfig[systemName] = systemConfig.router;
});
/* ******************************** 子系统配置信息加载 END ******************************** */

/* ******************************** 所有子系统中的页面路由配置加载 BEGIN ******************************** */
// 获取系统中配置的所有页面的路由配置，在封装路由对象时，将每个页面配置的特有的路由配置再次封装至路由配置中
const routerConfig = {};
const configContext = require.context('@/modules', true, /\/config\/router.js$/);
configContext.keys().forEach(key => {
  const systemName = key.split('/')[1];
  // 如果当前子系统不需要封装，则不进行封装
  if (!utils.hasSystem(systemName)) {
    return;
  }
  let path = '';
  if (key.indexOf('./') === 0) {
    path = key.split('./')[1] || '';
  }
  path = path.split('/config/router.js')[0] || '';
  const configName = utils.getCamelName(path);
  routerConfig[configName] = configContext(key).default;
});
/* ******************************** 所有子系统中的页面路由配置加载 END ******************************** */

/* ******************************** 所有子系统中的页面加载，通知进行路由配置 BEGIN ******************************** */
const modulesRoutersMap = {};
const dependPaths = {};
const routerContext = require.context('@/modules', true, /\/pages\/.*\.vue$/);
routerContext.keys().forEach(key => {
  let path = key || '';
  const systemName = key.split('/')[1];
  // 如果当前子系统不需要封装，则不进行封装
  if (!utils.hasSystem(systemName)) {
    return;
  }
  let globalConfig = {};
  if (systemRouterConfig && systemRouterConfig[systemName]) {
    globalConfig = JSON.parse(JSON.stringify(systemRouterConfig[systemName]))
  }
  // 重新截取页面对应的vue文件地址，用于封装绝对地址
  if (path.indexOf('./') === 0) {
    path = path.split('./')[1] || '';
  }
  if (path && path.length) {
    // 去掉路由中的pages路径
    let routerPath = path.split('/pages/').join('/');
    let configPath = utils.getCamelName(path.split('/pages/')[0]);
    let extendConfig = {};
    if (routerConfig[configPath]) {
      let configName = utils.getCamelName(path.split('/pages/')[1], true);
      configName = configName.split('.')[0];
      extendConfig = routerConfig[configPath][configName];
    }
    routerPath = '/' + (routerPath || '').split('.')[0];
    const pathName = utils.getCamelName(routerPath);
    const routerInfo = {
      path: routerPath,
      name: pathName,
      component: () => import(`@/modules/${path}`),
      // 将当前系统对应的全局路由配置文件保存至当前路由配置中
      meta: globalConfig.meta
    };
    const routeItem = utils.deepObjectMerge(routerInfo, extendConfig);
    // if (routeItem.meta && routeItem.meta.pathParam && routeItem.meta.pathParam.length) {
    //   routeItem.path += routeItem.meta.pathParam;
    // }
    routetList.push({ ...routeItem });

    // 如果当前路由有依赖的页面，则将当前路由地址封装至依赖路由配置中，用于保存至具体路由的子路由中
    if (routeItem.meta && routeItem.meta.dependPath && routeItem.meta.dependPath.length) {
      let dependName = utils.getCamelName(routeItem.meta.dependPath);
      dependPaths[dependName] = dependPaths[dependName] || [];
      dependPaths[dependName].push(routeItem);
    } else {
      modulesRoutersMap[pathName] = routeItem;
    }
  }
});
/* ******************************** 所有子系统中的页面加载，通知进行路由配置 END ******************************** */

/* ******************************** 根据页面路由中的路由依赖，配置完整的系统路由 EBGIN ******************************** */
const modulesRoutersList = [];
for (let key in modulesRoutersMap) {
  let router = modulesRoutersMap[key];
  if (router && router.path) {
    if (dependPaths[router.name] && dependPaths[router.name].length) {
      router.children = router.children || [];
      router.children = router.children.concat(dependPaths[router.name]);
    }
    modulesRoutersList.push(router);
  }
}
/* ******************************** 根据页面路由中的路由依赖，配置完整的系统路由 END ******************************** */

store.commit(cacheKeys.CACHE_ROUTER_LIST, routetList);
store.commit(cacheKeys.CACHE_SYSTEM_LIST, systemList);

log.debug('当前系统路由为：', modulesRoutersList);

export default modulesRoutersList